#pragma once
#include "SDL.h"
#include "baseobject.h"


//class ColorRGB;
//class ColorRGBA;
class GameCore;

namespace EPOC
{
	
	class ColorRGB;
	class ColorRGBA;
	enum WINDOWPOSITIONMODE
	{
		UNDEFINED,
		CENTERED,
		DEFINED
	};

	enum
	{
		VSYNC			= (1 << 0),
		WINDOWSTATE		= (1 << 1),
		RENDERMODE		= (1 << 2),
		WINDOWPOSITION	= (1 << 3),
		BACKBUFFERS		= (1 << 4)
	};
	typedef Uint32 GraphicsDeviceDirtyFlags;


	class GraphicsDevice : public BaseObject
	{
	public:
		GraphicsDevice();
		virtual ~GraphicsDevice();

	public:
		void ApplyChanges();
		void Clear(ColorRGB color);
		void Clear(ColorRGBA color);
		void SetWindowPosition(int x, int y);
		void GetWindowPosition(int &x, int &y);

#pragma region Inlines
		inline const SDL_Window* GetWindow()						{return window;}
		inline const SDL_Renderer* GetRenderer()					{return renderer;}
		inline const SDL_RendererInfo* GetRendererInfo()			{return &rendererInfo;}

		inline bool IsSynchronizeWithVerticalRetraceEnabled()		{ return synchronizeWithVerticalRetrace;}
		inline void SetSynchronizeWithVerticalRetrace(bool state)	{ if(synchronizeWithVerticalRetrace != state) SetDirty(VSYNC); synchronizeWithVerticalRetrace = state;}
		
		inline bool IsFullscreenEnabled()							{ return fullscreen;}
		inline void SetFullscreen(bool state)						{ if(fullscreen != state) SetDirty(WINDOWSTATE); fullscreen = state; fullscreenDesktop = !state;}

		inline bool IsFullscreenDesktopEnabled()					{ return fullscreenDesktop;}
		inline void SetFullscreenDesktop(bool state)				{ if(fullscreenDesktop != state) SetDirty(WINDOWSTATE); fullscreenDesktop = state; fullscreen = !state;}

		inline bool IsOpenGLEnabled()								{ return useOpenGL;}
		inline void SetOpenGL(bool state)							{ if(useOpenGL != state) SetDirty(RENDERMODE); useOpenGL = state;}

		inline void SetWindowPositionMode(WINDOWPOSITIONMODE mode)				{if(windowPositionMode != mode) SetDirty(WINDOWSTATE); windowPositionMode = mode;}
		inline WINDOWPOSITIONMODE GetWindowPositionMode(WINDOWPOSITIONMODE mode){ return windowPositionMode;}

	public:		
		inline void SetPreferredBackBufferWidth(int width)			{ if(preferredBackBufferWidth != width) SetDirty(BACKBUFFERS); preferredBackBufferWidth = width;}
		inline void SetPreferredBackBufferHeight(int height)		{ if(preferredBackBufferHeight != height) SetDirty(BACKBUFFERS); preferredBackBufferHeight = height;}
		inline int GetPreferredBackBufferWidth()					{ return preferredBackBufferWidth;}
		inline int GetPreferredBackBufferHeight()					{ return preferredBackBufferHeight;}
#pragma endregion


	private:
		void Initialize();

		inline void SetDirty(GraphicsDeviceDirtyFlags flag) { dirtyFlags |= flag;}
		inline bool IsDirty(GraphicsDeviceDirtyFlags flag) { return dirtyFlags & flag;}
		

	private:

		GraphicsDeviceDirtyFlags dirtyFlags;
	
		bool synchronizeWithVerticalRetrace;
		bool fullscreen;
		bool fullscreenDesktop;
		bool useOpenGL;

		WINDOWPOSITIONMODE windowPositionMode;
		
		int windowPositionX;
		int windowPositionY;
		int preferredBackBufferWidth;
		int preferredBackBufferHeight;

		SDL_Window* window;
		SDL_Renderer* renderer;
		SDL_RendererInfo rendererInfo;
	};
};

